package com.wayhome.demo.sentinal.controller;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

@RestController
@Slf4j
public class SentinelDemoController {

    private static final String RESOURCE = "hello";

//    @PostConstruct
//    private static  void initFlowRules(){
//        List<FlowRule> flowRuleList = new ArrayList<>();
//        FlowRule flowRule = new FlowRule();
//        flowRule.setResource(RESOURCE);
//        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
//        flowRule.setCount(1);
//        flowRuleList.add(flowRule);
//        FlowRuleManager.loadRules(flowRuleList);
//    }

//    @GetMapping(value = "/hello")
//
//    public String helloSentinel(){
//        Entry entry = null;
//        try {
//            entry = SphU.entry(RESOURCE);
//            return "Hello sentinel";
//        } catch (Exception e) {
//            Tracer.traceEntry(e,entry);
//            return "降级处理";
//        }finally {
//            if (entry != null){
//                entry.exit();
//            }
//        }
//    }

    /**
     *  注解 @SentinelResource：
     *  value = RESOURCE --声明资源
     *  fallback--出现异常时的降级处理，fallbackClass 指定降级处理的类，注意如果指定了，那么降级方法一定得是static的
     *    exceptionsToIgnore 忽略异常，即碰到这类异常不做降级处理
     *  blockHandler--被流控时的处理，blockHandlerClass 指定流控处理的类，方法也必须是static的
     *  如果fallback和blockHandler同时存在，那么blockHandler的优先级 > fallback
     *
     */
    @GetMapping(value = "/hello")
    @SentinelResource(value = RESOURCE,
            //fallbackClass = {Fullback.class},
            // exceptionsToIgnore={RuntimeException.class}
            fallback = "fullbackHandler",
            //,blockHandlerClass = {BlockHandler.class}
            blockHandler = "blockHandler"
    )
    public String hello(){
        return "hello sentinel";
    }

    public String blockHandler(){
        return "流控处理";
    }

    public String fullbackHandler(){
        return "降级处理";
    }
}
